Skip to content

HDDS-15067. Conditional CompleteMultipartUpload#10164

Merged
peterxcli merged 5 commits intoapache:masterfrom
YutaLin:HDDS-15067_CompleteMultipartUpload
May 4, 2026
Merged

HDDS-15067. Conditional CompleteMultipartUpload#10164
peterxcli merged 5 commits intoapache:masterfrom
YutaLin:HDDS-15067_CompleteMultipartUpload

Conversation

@YutaLin
Copy link
Copy Markdown
Contributor

@YutaLin YutaLin commented Apr 30, 2026

What changes were proposed in this pull request?

Conditional CompleteMultipartUpload

Please describe your PR in detail:

Conditional MPU completion should reuse the same conditional write fields already present in KeyArgs, but unlike normal conditional PUT, it does not need an open-key plus later commit bridge. The final key is assembled and committed inside one OM transaction in S3MultipartUploadCompleteRequest.validateAndUpdateCache(...) while holding the normal bucket write lock

What is the link to the Apache JIRA

https://issues.apache.org/jira/browse/HDDS-15067

How was this patch tested?

Add E2E tests, CI Action(https://github.com/YutaLin/ozone/actions/runs/25147780358)

@YutaLin
Copy link
Copy Markdown
Contributor Author

YutaLin commented Apr 30, 2026

Hi @peterxcli @ivandika3
Could you review this? Appreciate!

@peterxcli peterxcli requested review from ivandika3 and peterxcli May 1, 2026 09:11
Copy link
Copy Markdown
Member

@peterxcli peterxcli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@YutaLin Thanks for the patch, left some comments, the rest looks good.

By the way, could you help me reason about how we can return a 409 in the presence of concurrent requests? Specifically, if two or more independent clients send the exact same Complete Multipart Upload request at the same time, only one client should receive a successful response and the others should get a 409. That way, they know they must re-read the object, re-upload the parts if necessary, and then complete the MPU again using the latest ETag they observed.

ref:

  • https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html

    If-Match
    Uploads the object only if the ETag (entity tag) value provided during the WRITE operation matches the ETag of the object in S3. If the ETag values do not match, the operation returns a 412 Precondition Failed error.

    If a conflicting operation occurs during the upload S3 returns a 409 ConditionalRequestConflict response. On a 409 failure you should fetch the object's ETag, re-initiate the multipart upload with CreateMultipartUpload, and re-upload each part.

  • #10043

@peterxcli
Copy link
Copy Markdown
Member

@YutaLin could you also help me to take a look if we need to clear the etag field and expected data gen field?

omKeyInfo.setExpectedDataGeneration(null);
omKeyInfo.setExpectedETag(null);

@peterxcli
Copy link
Copy Markdown
Member

@YutaLin please re-request my review if think this is ready, thanks!

@ivandika3 ivandika3 added ozone-local HDDS-14893 and removed ozone-local HDDS-14893 labels May 3, 2026
@ivandika3 ivandika3 changed the title HDDS-15067. Complete Multipart upload HDDS-15067. Conditional CompleteMultipartUpload May 3, 2026
@YutaLin
Copy link
Copy Markdown
Contributor Author

YutaLin commented May 3, 2026

omKeyInfo.setExpectedDataGeneration(null);
omKeyInfo.setExpectedETag(null);

Hi @peterxcli
We need to set them null for now, otherwise, they'll be stored in KeyTable later, which we don't want.
Once we've completed #10181, setting them to null will no longer be necessary, as the codec will prevent them from being stored in the KeyTable.

@YutaLin
Copy link
Copy Markdown
Contributor Author

YutaLin commented May 3, 2026

@YutaLin Thanks for the patch, left some comments, the rest looks good.

By the way, could you help me reason about how we can return a 409 in the presence of concurrent requests? Specifically, if two or more independent clients send the exact same Complete Multipart Upload request at the same time, only one client should receive a successful response and the others should get a 409. That way, they know they must re-read the object, re-upload the parts if necessary, and then complete the MPU again using the latest ETag they observed.

ref: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html

If-Match
Uploads the object only if the ETag (entity tag) value provided during the WRITE operation matches the ETag of the object in S3. If the ETag values do not match, the operation returns a 412 Precondition Failed error.
If a conflicting operation occurs during the upload S3 returns a 409 ConditionalRequestConflict response. On a 409 failure you should fetch the object's ETag, re-initiate the multipart upload with CreateMultipartUpload, and re-upload each part.

Hi @peterxcli
Conditional Request conflict can't happen because MPU completion uses pessimistic lock, meaning there's no race window between validation and commit.

I will make comments in file.

@YutaLin YutaLin requested a review from peterxcli May 3, 2026 23:06
@peterxcli
Copy link
Copy Markdown
Member

Hi @peterxcli
We need to set them null for now, otherwise, they'll be stored in KeyTable later, which we don't want.
Once we've completed #10181, setting them to null will no longer be necessary, as the codec will prevent them from being stored in the KeyTable.

yeah, for the key commit request, your statement is true, but I'm asking if S3MultipartUploadCompleteRequest we touched need to do the same thing.

Copy link
Copy Markdown
Member

@peterxcli peterxcli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @YutaLin for updating the patch. LGTM +1!

@YutaLin
Copy link
Copy Markdown
Contributor Author

YutaLin commented May 4, 2026

Hi @peterxcli,
In S3MultipartUploadCompleteRequest, we don't have to do that because those fields are not set in OpenKeyTable during the mpu process. We validate conditional resource(keyArgs) against the existing Keyinfo from the KeyTable.

For put requests, however, the conditional resource comes from the OpenKeyTable. Since it may already contain conditional values when stored, we need to set them to null beforehand.

@peterxcli
Copy link
Copy Markdown
Member

Hi @peterxcli Conditional Request conflict can't happen because MPU completion uses pessimistic lock, meaning there's no race window between validation and commit.

yeah, I know, but the spec looks like AWS S3 can detect such cases and return 409.
Let me think about it more. For now, let’s just merge the current patch.

@peterxcli peterxcli self-requested a review May 4, 2026 07:43
@peterxcli peterxcli merged commit 3369728 into apache:master May 4, 2026
90 of 91 checks passed
@peterxcli
Copy link
Copy Markdown
Member

Thanks @YutaLin for the patch!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants